package org.acme.server.utils;

/**
 * @author chentao
 * @version 1.0
 * @description: TODO
 * @date 2025/3/7 下午11:12
 */
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;

public class IPUtils {

    /****
     * 获取本地IP地址
     * @return
     */
    public static String getIP() {
        String ip = "127.0.0.1";
        try {
            InetAddress localHost = getLocalHostExactAddress();
            ip = localHost.getHostAddress();
        } catch (Exception e) {
            System.out.print("获取本地IP失败: " + e.getMessage());
        }
        return ip;
    }


    /****
     * 获取本地IP地址
     * @return
     * @throws Exception
     */
    public static InetAddress getLocalHostExactAddress() throws Exception {
        InetAddress candidateAddress = null;
        Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
        while (networkInterfaces.hasMoreElements()) {
            NetworkInterface iface = networkInterfaces.nextElement();
            for (Enumeration<InetAddress> inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements(); ) {
                InetAddress inetAddr = inetAddrs.nextElement();
                if (!inetAddr.isLoopbackAddress()) {
                    if (inetAddr.isSiteLocalAddress()) {
                        return inetAddr;
                    }
                    if (candidateAddress == null) {
                        candidateAddress = inetAddr;
                    }

                }
            }
        }
        return candidateAddress == null ? InetAddress.getLocalHost() : candidateAddress;
    }

    /****
     * 把IP地址和端口合并成一个长整型的数字。
     * @param ipAddress
     * @param port
     * @return
     */
    public static long combineIpAndPort(String ipAddress, long port) {
        long ipAsLong = toDecimal(ipAddress);
        return (ipAsLong << 16) | (port & 0xFFFF);
    }

    /****
     * 把IP地址转成长整型数字
     * @param ipAddress
     * @return
     */
    public static long toDecimal(String ipAddress) {
        String[] parts = ipAddress.split("\\.");
        long result = 0;
        for (int i = 0; i < parts.length; i++) {
            int value = Integer.parseInt(parts[i]);
            result += value << (24 - (i * 8));
        }
        return result & 0xFFFFFFFFL;
    }

    /****
     * 把长整数转成IP地址
     * @param decimalIpAddress
     * @return
     */
    public static String fromDecimal(long decimalIpAddress) {
        StringBuilder ipAddressBuilder = new StringBuilder();
        for (int i = 0; i < 4; i++) {
            int shift = 24 - (i * 8);
            int value = (int) ((decimalIpAddress >> shift) & 0xFF);
            ipAddressBuilder.append(value);
            if (i < 3) {
                ipAddressBuilder.append(".");
            }
        }
        return ipAddressBuilder.toString();
    }

    /***
     * 把长整型数字分解成IP地址和端口信息
     * @param combined
     * @return
     */
    public static String[] splitIpAndPort(long combined) {
        long ipAsLong = (combined >> 16) & 0xFFFFFFFFL;
        int port = (int) (combined & 0xFFFF);
        String ipAddress = fromDecimal(ipAsLong);
        return new String[]{ipAddress, String.valueOf(port)};
    }
}
